//! Structures relating to block and entity updates.

use craftdig_datamodel::{block::BlockStateSnapshot, entity::EntityId};
use craftdig_math::{BlkCoord, Vec3f};

/// Describes a requested change to a block which hasn't been applied yet.
///
/// When applying, should generate:
/// * a destroy message to pre-block, before changing the chunk,
/// * place messages to itself,
/// * and update messages neighbors
#[derive(Clone, Debug)]
pub struct BlockChange {
    target_pos: BlkCoord,
    data: BlockChangeData,
}

impl BlockChange {
    pub fn new_snapshot(target_pos: BlkCoord, snapshot: BlockStateSnapshot) -> Self {
        Self {
            target_pos,
            data: BlockChangeData {
                new_state: snapshot,
            },
        }
    }

    /// Target position, which is the block that's actually updating.
    pub fn target_pos(&self) -> BlkCoord {
        self.target_pos
    }

    /// New block state.
    pub fn new_state(&self) -> &BlockStateSnapshot {
        &self.data.new_state
    }
}

#[derive(Clone, Debug)]
struct BlockChangeData {
    new_state: BlockStateSnapshot,
}

/// Describes some change to a particular entity.
#[derive(Clone, Debug)]
pub struct EntityUpdate {
    entity_id: EntityId,
    data: EntityUpdateData,
}

impl EntityUpdate {
    pub fn new(entity_id: EntityId, data: EntityUpdateData) -> Self {
        Self { entity_id, data }
    }

    pub fn entity_id(&self) -> EntityId {
        self.entity_id
    }

    pub fn data(&self) -> &EntityUpdateData {
        &self.data
    }
}

#[derive(Clone, Debug)]
pub enum EntityUpdateData {
    /// Moves the entity to some position without transiting the space in between.
    MoveTo(Vec3f),

    /// Adds some value to the entity's velocity.
    AddVelocity(Vec3f),

    /// Resets the velocity to some value.
    ///
    /// Makes no guarantees about how `AddVelocity` behaves with relation.
    ResetVelocity(Vec3f),
}

impl EntityUpdateData {
    pub fn on(self, eid: EntityId) -> EntityUpdate {
        EntityUpdate::new(eid, self)
    }
}
